import wx from '../subwe/bridge'
import CONST from "./const"
import {strToArrayBuffer, ab2hex, BluetoothMac, BluetoothPowerMinute, toTenDecimal} from './util'
import { Index } from '../apis/index'
const API = new Index()
// const GetAutomatePdPassword = API.resetPassword

class Bluetooth {
    constructor(options) {
        this.options = options || {}
        this.connectionDevices = this.getConnectionDevices(this.options.deviceSn)
    }

    // 初始化
    openBluetoothAdapter() {
        console.log('class openBluetoothAdapter')
        return new Promise((resolve, reject) => {
            my.openBluetoothAdapter({
                success(res) {
                    resolve(res)
                },
                fail(res) {
                    reject(res)
                }
            })
        })
    }

    // 搜索蓝牙设备
    startBluetoothDevicesDiscovery() {
        console.log('class startBluetoothDevicesDiscovery')
        return new Promise(async (resolve, reject) => {
            let connectionDevices = this.getConnectionDevices()
            let connectionResult = await this.getBaseConnectedDevices(connectionDevices)
            console.log('getBaseConnectedDevices', connectionResult)
            if (connectionResult && connectionResult.deviceId) return resolve(connectionResult)

            console.log('startBluetoothDevicesDiscovery-start', this.options)
            my.startBluetoothDevicesDiscovery({
                allowDuplicatesKey: true,
                success: (res) => {
                    my.onBluetoothDeviceFound(dRes => {
                        let devices = dRes.devices
                        console.log('class onBluetoothDeviceFound', devices)
                        for (let device of devices) {
                            let deviceSn = device.name || device.localName
                            if (this.options.deviceSn === deviceSn) {
                                clearTimeout(this.options.bluetoothTime)
                                this.stopBluetoothDevicesDiscovery(device)
                                this.options.bluetoothTime = setTimeout(ev => resolve(device), 80)
                            }
                        }
                    })
                },
                fail(res) {
                    reject(res)
                }
            })
        })
    }

    stopBluetoothDevicesDiscovery(device) {
        my.stopBluetoothDevicesDiscovery({
            complete: (res) => {
                console.log('stopBluetoothDevicesDiscovery', res, device)
            }
        })
    }

    // 查询连接状态
    async getBaseConnectedDevices(connectionDevices) {
        return new Promise(async (resolve, reject) => {
            console.log('getBaseConnectedDevices', connectionDevices)
            if (!connectionDevices.writeServer) return resolve(false)

            let devices = await this.getConnectedBluetoothDevices(connectionDevices.writeServer)
            console.log('await this.getConnectedBluetoothDevices', devices, connectionDevices)
            for (let device of devices) if (device.deviceId === connectionDevices.writeServer.deviceId) {
                return resolve(connectionDevices.writeServer)
            }

            this.deleteConnectionDevices(this.options.deviceSn)
            resolve(false)
        })
    }

    // 连接蓝牙 并获取服务列表
    createBLEConnection(deviceId) {
        console.log('class createBLEConnection')
        return new Promise((resolve, reject) => {
            my.connectBLEDevice({
                deviceId,
                success(res) {
                    my.getBLEDeviceServices({
                        deviceId,
                        success(sRes) {
                            let services = sRes.services
                            for(let item of services) if(!item.uuid) item.uuid = item.serviceId
                            console.log('getBLEDeviceServices', services, sRes)
                            resolve(services)
                        },
                        fail(res) {
                            reject(res)
                        }
                    })
                },
                fail(res) {
                    reject(res)
                }
            })
        })
    }

    // 服务中所有特征值
    getBLEDeviceCharacteristics(deviceId, service) {
        console.log('class getBLEDeviceCharacteristics', deviceId, service)
        return new Promise((resolve, reject) => {
            my.getBLEDeviceCharacteristics({
                deviceId,
                serviceId: service.uuid,
                success(res) {
                    resolve(res.characteristics)
                },
                fail(res) {
                    reject(res)
                }
            })
        })
    }

    // 服务中所有特征值
    getBLEDeviceCharacteristicsAll(deviceId, services) {
        console.log('class getBLEDeviceCharacteristicsAll', deviceId, services)
        return new Promise(async (resolve, reject) => {
            let characteristicAllList = [], characteristics
            for (let service of services) {
                try {
                    characteristics = await this.getBLEDeviceCharacteristics(deviceId, service)
                } catch (res) {
                    return reject(res)
                }
                for (let characteristic of characteristics) {
                    characteristic.deviceId = deviceId
                    characteristic.serviceId = service.uuid
                    characteristic.characteristicId = characteristic.uuid || characteristic.characteristicId
                    characteristicAllList.push(characteristic)
                }
            }
            resolve(characteristicAllList)
        })
    }

    // 订阅特征值
    notifyBLECharacteristicValueChange(characteristic, notifyFn) {
        console.log('class notifyBLECharacteristicValueChange', characteristic)
        return new Promise(async (resolve, reject) => {
            my.onBLECharacteristicValueChange(nRes => {
                console.log('my.onBLECharacteristicValueChange', nRes)
                if (notifyFn instanceof Function) notifyFn(nRes)
            })

            await this.timeSleep(10)
            let {deviceId, serviceId, characteristicId} = characteristic
            my.notifyBLECharacteristicValueChange({
                state: true, deviceId, serviceId, characteristicId,
                success(res) {
                    console.log('my.notifyBLECharacteristicValueChange', res)
                    resolve(res)
                },
                fail(res) {
                    reject(res)
                }
            })
        })
    }

    // 写入二进制数据
    writeBLECharacteristicValue(characteristic, value) {
        console.log('class writeBLECharacteristicValue', characteristic, value)
        return new Promise((resolve, reject) => {
            let {deviceId, serviceId, characteristicId} = characteristic
            my.writeBLECharacteristicValue({
                deviceId, serviceId, characteristicId, value: strToArrayBuffer(value),
                success(res) {
                    resolve(res)
                },
                fail(res) {
                    reject(res)
                }
            })
        })
    }

    // 连接状态的设备
    getConnectedBluetoothDevices(characteristic) {
        console.log('class getConnectedBluetoothDevices', characteristic)
        return new Promise((resolve, reject) => {
            my.getConnectedBluetoothDevices({
                // services: [characteristic.serviceId],
                success(res) {
                    resolve(res.devices)
                },
                fail(res) {
                    reject(res)
                }
            })
        })
    }

    // 断开连接
    closeBLEConnection(characteristic) {
        return new Promise((resolve, reject) => {
            let {deviceId} = characteristic
            my.disconnectBLEDevice({
                deviceId,
                success(res) {
                    resolve(res)
                },
                fail(res) {
                    reject(res)
                }
            })
        })
    }

    // 记录连接服务
    saveConnectionDevices(deviceSn, data) {
        console.log('saveConnectionDevices', deviceSn, data)
        wx.setStorageSync(`BLE-${deviceSn}`, data)
        this.connectionDevices = data
    }

    getConnectionDevices(deviceSn) {
        return this.connectionDevices || wx.getStorageSync(`BLE-${deviceSn}`) || {}
    }

    deleteConnectionDevices(deviceSn) {
        wx.setStorageSync(`BLE-${deviceSn}`, undefined)
        this.connectionDevices = undefined
    }

    timeSleep(t) {
        return new Promise((resolve, reject) => {
            setTimeout(ev => resolve(ev), t)
        })
    }
}

// 蓝牙密码组连接
class BluetoothGroupPassword extends Bluetooth {
    async initConnection() {
        try {
            console.log('initConnection-start')
            await this.openBluetoothAdapter()

            let characteristic = this.getConnectionDevices()
            if (await this.getConnectedDevices(characteristic)) return

            let device = this.options.device
            if(!device || !device.deviceId) device = await this.startBluetoothDevicesDiscovery()

            let services = await this.createBLEConnection(device.deviceId)
            let characteristicAllList = await this.getBLEDeviceCharacteristicsAll(device.deviceId, services)
            console.log('characteristicAllList', characteristicAllList)

            for (let characteristic of characteristicAllList) {
                if (characteristic.characteristicId.toUpperCase().indexOf('FFF4') > -1) {
                    await this.notifyValueChange(characteristic)
                    await this.writeValue(characteristic)

                    this.saveConnectionDevices(this.options.deviceSn, {
                        writeServer: characteristic, notifyServer: characteristic
                    })
                    break
                }
            }
        } catch (err) {
            console.log('initConnection', err)
            if (this.options.fail instanceof Function) this.options.fail(err)
        }
    }

    // 查询连接状态
    getConnectedDevices(connectionDevices) {
        return new Promise(async (resolve, reject) => {
            console.log('getConnectedDevices', connectionDevices)
            if (!connectionDevices.writeServer) return resolve(false)
            let devices = await this.getConnectedBluetoothDevices(connectionDevices.writeServer)
            for (let device of devices) if (device.deviceId === connectionDevices.writeServer.deviceId) {
                await this.notifyValueChange(connectionDevices.notifyServer)
                await this.writeValue(connectionDevices.writeServer)
                return resolve(true)
            }
            this.deleteConnectionDevices(this.options.deviceSn)
            resolve(false)
        })
    }

    notifyValueChange(characteristic) {
        console.log('notifyValueChange', characteristic)
        return new Promise(async (resolve, reject) => {
            let res = await this.notifyBLECharacteristicValueChange(characteristic, nRes => {
                let value = nRes.value.toUpperCase()
                console.log('notifyBLECharacteristicValueChange', value, nRes)
                if (value.indexOf('F00100') > -1 || value.indexOf('F00200') > -1 || value.indexOf('F00300') > -1 || value.indexOf('F10100') > -1) {
                    if (this.options.success instanceof Function) this.options.success(value)
                    if(this.options.closeBLEConnectionOff) this.closeBLEConnection(characteristic)
                    return
                }
                if (this.options.fail instanceof Function) this.options.fail(value)
            })
            resolve(res)
        })

    }

    writeValue(characteristic) {
        console.log('writeValue', characteristic, this.options)
        return new Promise(async (resolve, reject) => {

            if (this.options.type === CONST.BluetoothTypeOffCharge) {
                let wRes = await this.writeBLECharacteristicValue(characteristic, '050505050505')
                return resolve(wRes)
            }

            const loginInfo = wx.getStorageSync('login_key')
            const paramPassword = { deviceSn: this.options.deviceSn, openid: loginInfo.openid }
            API.resetPassword(paramPassword).then(async res => {
                console.log('GetAutomatePdPassword', res)
                if(!res.result || !res.result.password) return reject('password err')

                let uuids = res.result.password
                if (this.options.type === CONST.BluetoothTypeStartCharge) uuids = '0' + uuids.split('').join('0')
                else if (this.options.type === CONST.BluetoothTypeStartChannelOne) uuids = 'A10' + uuids.slice(1).split('').join('0')
                else if (this.options.type === CONST.BluetoothTypeStartChannelTwo) uuids = 'A20' + uuids.slice(1).split('').join('0')
                else return reject('type is err')

                await this.timeSleep(800)
                let wRes = await this.writeBLECharacteristicValue(characteristic, uuids)
                resolve(wRes)
            }).catch(err => {
                reject(err)
            })
        })
    }
}

// 蓝牙密码组连接-XM
class BluetoothGroupPasswordXm extends Bluetooth {
    async initConnection() {
        try {
            console.log('initConnection-start')
            await this.openBluetoothAdapter()
            
            let characteristic = this.getConnectionDevices()
            if (await this.getConnectedDevices(characteristic)) return
            
            let device = this.options.device
            if(!device || !device.deviceId) device = await this.startBluetoothDevicesDiscovery()
            
            let services = await this.createBLEConnection(device.deviceId)
            let characteristicAllList = await this.getBLEDeviceCharacteristicsAll(device.deviceId, services)
            console.log('characteristicAllList', characteristicAllList)
            
            let saveData = {}
            for (let characteristic of characteristicAllList) {
                if (characteristic.characteristicId.toUpperCase().indexOf('FF12') > -1) {
                    saveData.writeServer = characteristic
                }
                if (characteristic.characteristicId.toUpperCase().indexOf('FFF4') > -1) {
                    saveData.notifyServer = characteristic
                }
            }
            
            if(!saveData.writeServer || !saveData.notifyServer ) {
                if (this.options.fail instanceof Function) this.options.fail('设备暂不支持')
                return
            }
            
            await this.notifyValueChange(saveData.notifyServer)
            await this.writeValue(saveData.writeServer)
            this.saveConnectionDevices(this.options.deviceSn, saveData)
        } catch (err) {
            console.log('initConnection', err)
            if (this.options.fail instanceof Function) this.options.fail(err)
        }
    }
    
    // 查询连接状态
    getConnectedDevices(connectionDevices) {
        return new Promise(async (resolve, reject) => {
            console.log('getConnectedDevices', connectionDevices)
            if (!connectionDevices.writeServer) return resolve(false)
            let devices = await this.getConnectedBluetoothDevices(connectionDevices.writeServer)
            for (let device of devices) if (device.deviceId === connectionDevices.writeServer.deviceId) {
                await this.notifyValueChange(connectionDevices.notifyServer)
                await this.writeValue(connectionDevices.writeServer)
                return resolve(true)
            }
            this.deleteConnectionDevices(this.options.deviceSn)
            resolve(false)
        })
    }
    
    notifyValueChange(characteristic) {
        console.log('notifyValueChangeXM', characteristic)
        return new Promise(async (resolve, reject) => {
            let res = await this.notifyBLECharacteristicValueChange(characteristic, nRes => {
                console.log('notifyBLECharacteristicValueChangeXm', nRes)
                let value = (nRes.value || '').toUpperCase()
                if (value.indexOf('F10100') > -1 || value.indexOf('F10200') > -1) {
                    if (this.options.success instanceof Function) this.options.success(value)
                    if(this.options.closeBLEConnectionOff) this.closeBLEConnection(characteristic)
                    return
                }
                if (this.options.fail instanceof Function) this.options.fail(value)
            })
            resolve(res)
        })
        
    }
    
    writeValue(characteristic) {
        console.log('writeValue', characteristic, this.options)
        return new Promise(async (resolve, reject) => {
            
            if (this.options.type === CONST.BluetoothTypeOffCharge) {
                let wRes = await this.writeBLECharacteristicValue(characteristic, '050505050505')
                return resolve(wRes)
            }
            
            let uuids = `F101${BluetoothPowerMinute(this.options.powerMinute || 10)}000A`
            console.log('GetAutomatePdPassword-xm', uuids)
            if (this.options.type === CONST.BluetoothTypeStartCharge){}
            else return reject('type is err')
            
            await this.timeSleep(800)
            let wRes = await this.writeBLECharacteristicValue(characteristic, uuids)
            resolve(wRes)
            
            // const loginInfo = wx.getStorageSync('login_key')
            // const paramPassword = { deviceSn: this.options.deviceSn, openid: loginInfo.openid }
            // API.resetPassword(paramPassword).then(async res => {
            //     console.log('GetAutomatePdPassword', res)
            //     if(!res.result || !res.result.password) return reject('password err')
            //
            //     let uuids = res.result.password
            //     if (this.options.type === CONST.BluetoothTypeStartCharge) uuids = '0' + uuids.split('').join('0')
            //     else if (this.options.type === CONST.BluetoothTypeStartChannelOne) uuids = 'A10' + uuids.slice(1).split('').join('0')
            //     else if (this.options.type === CONST.BluetoothTypeStartChannelTwo) uuids = 'A20' + uuids.slice(1).split('').join('0')
            //     else return reject('type is err')
            //
            //     await this.timeSleep(800)
            //     let wRes = await this.writeBLECharacteristicValue(characteristic, uuids)
            //     resolve(wRes)
            // }).catch(err => {
            //     reject(err)
            // })
        })
    }
}

// 蓝牙动态密码连接
class BluetoothChangePassword extends Bluetooth {
    async initConnection() {
        try {
            console.log('initConnection-start')
            await this.openBluetoothAdapter()

            let connectionDevices = this.getConnectionDevices()
            if (await this.getConnectedDevices(connectionDevices)) return

            let device = this.options.device
            if(!device || !device.deviceId) device = await this.startBluetoothDevicesDiscovery()

            let services = await this.createBLEConnection(device.deviceId)
            let characteristicAllList = await this.getBLEDeviceCharacteristicsAll(device.deviceId, services)
            console.log('characteristicAllList', characteristicAllList)

            let saveData = {}
            for (let characteristic of characteristicAllList) {
                if (characteristic.characteristicId.toUpperCase().indexOf('AE01') > -1) {
                    saveData.writeServer = characteristic
                }
                if (characteristic.characteristicId.toUpperCase().indexOf('AE02') > -1) {
                    saveData.notifyServer = characteristic
                }
            }

            if(!saveData.writeServer || !saveData.notifyServer ) {
                if (this.options.fail instanceof Function) this.options.fail('设备暂不支持')
                return
            }

            await this.notifyValueChange(saveData)
            this.saveConnectionDevices(this.options.deviceSn, saveData)
        } catch (err) {
            console.log('initConnection', err)
            if (this.options.fail instanceof Function) this.options.fail(err)
        }
    }

    // 查询连接状态
    getConnectedDevices(connectionDevices) {
        return new Promise(async (resolve, reject) => {
            console.log('getConnectedDevices', connectionDevices)
            if (!connectionDevices.writeServer) return resolve(false)
            let devices = await this.getConnectedBluetoothDevices(connectionDevices.writeServer)
            for (let device of devices) if (device.deviceId === connectionDevices.writeServer.deviceId) {
                await this.notifyValueChange(connectionDevices)
                await this.writeValue(connectionDevices.writeServer)
                return resolve(true)
            }
            this.deleteConnectionDevices(this.options.deviceSn)
            resolve(false)
        })
    }

    notifyValueChange(connectionDevices) {
        console.log('notifyValueChange', connectionDevices)
        const { notifyServer, writeServer } = connectionDevices
        return new Promise(async (resolve, reject) => {
            let res = await this.notifyBLECharacteristicValueChange(notifyServer, nRes => {
                let value = nRes.value.toUpperCase()
                console.log('notifyBLECharacteristicValueChange', value, nRes)

                if(!writeServer.password) {
                    writeServer.password = value
                    this.saveConnectionDevices(this.options.deviceSn, { notifyServer, writeServer })

                    return this.writeValue(writeServer).then(res => {
                        clearTimeout(this.options.successTime)
                        if (this.options.success instanceof Function) this.options.success(res)
                    }).catch(err => {
                        clearTimeout(this.options.successTime)
                        if (this.options.fail instanceof Function) return this.options.fail(err)
                    })
                }

                if (['AE01', 'AE02', 'AE03', 'AE04', 'AE05'].indexOf(value) > -1) {
                    if (this.options.fail instanceof Function) this.options.fail(value)
                    return
                }

                clearTimeout(this.options.successTime)
                if (this.options.success instanceof Function) this.options.success(value)
            })

            resolve(res)
        })

    }

    writeValue(characteristic) {
        console.log('writeValue', characteristic, this.options)
        return new Promise(async (resolve, reject) => {

            let mac = BluetoothMac(this.options.bluetoothMac), uuids = '', key = '0927'
            if (this.options.deviceSn && this.options.deviceSn.indexOf('220709ZM') > -1) key = '1708'
            if (this.options.type === CONST.BluetoothTypeOffCharge) uuids = `0000${key}${mac[0]}${mac[1]}80FF0000`
            else if (this.options.type === CONST.BluetoothTypeStartCharge) uuids = `0000${key}${mac[0]}${mac[1]}800A${BluetoothPowerMinute(this.options.powerMinute)}`
            else return reject('type is err')

            uuids += toTenDecimal(characteristic.password)
            API.getDevPasswordVerify({ message: uuids }).then(async res => {
                console.log('getDevPasswordVerify', res)
                if(!res.result) return reject('password err')
                uuids += res.result

                await this.timeSleep(800)
                let wRes = await this.writeBLECharacteristicValue(characteristic, uuids)
                this.options.successTime = setTimeout(ev => {
                    if (this.options.success instanceof Function) this.options.success(wRes)
                }, 2600)
                resolve(wRes)
            }).catch(err => {
                reject(err)
            })
        })
    }
}

// 蓝牙密码连接[天盘设备]
class BluetoothPassword extends Bluetooth {
    async initConnection() {
        try {
            console.log('initConnection-start')
            await this.openBluetoothAdapter()

            let connectionDevices = this.getConnectionDevices()
            if (await this.getConnectedDevices(connectionDevices)) return

            let device = this.options.device
            if(!device || !device.deviceId) device = await this.startBluetoothDevicesDiscovery()

            let services = await this.createBLEConnection(device.deviceId)
            let characteristicAllList = await this.getBLEDeviceCharacteristicsAll(device.deviceId, services)
            console.log('characteristicAllList', characteristicAllList)

            let saveData = {}
            for (let characteristic of characteristicAllList) {
                if (characteristic.characteristicId.toUpperCase().indexOf('AE01') > -1) {
                    saveData.writeServer = characteristic
                }
                if (characteristic.characteristicId.toUpperCase().indexOf('AE02') > -1) {
                    saveData.notifyServer = characteristic
                }
            }

            if(!saveData.writeServer || !saveData.notifyServer ) {
                if (this.options.fail instanceof Function) this.options.fail('设备暂不支持')
                return
            }

            await this.notifyValueChange(saveData)
            await this.writeValue(saveData.writeServer)
            this.saveConnectionDevices(this.options.deviceSn, saveData)
        } catch (err) {
            console.log('initConnection', err)
            if (this.options.fail instanceof Function) this.options.fail(err)
        }
    }

    // 查询连接状态
    getConnectedDevices(connectionDevices) {
        return new Promise(async (resolve, reject) => {
            console.log('getConnectedDevices', connectionDevices)
            if (!connectionDevices.writeServer) return resolve(false)
            let devices = await this.getConnectedBluetoothDevices(connectionDevices.writeServer)
            for (let device of devices) if (device.deviceId === connectionDevices.writeServer.deviceId) {
                await this.notifyValueChange(connectionDevices)
                await this.writeValue(connectionDevices.writeServer)
                return resolve(true)
            }
            this.deleteConnectionDevices(this.options.deviceSn)
            resolve(false)
        })
    }

    notifyValueChange(connectionDevices) {
        console.log('notifyValueChange', connectionDevices)
        const { notifyServer, writeServer } = connectionDevices
        return new Promise(async (resolve, reject) => {
            let res = await this.notifyBLECharacteristicValueChange(notifyServer, nRes => {
                let value = nRes.value.toUpperCase()
                clearTimeout(this.options.successTime)
                console.log('notifyBLECharacteristicValueChange', value, nRes)

                if (value.slice(0,2) === "00") {
                    if (this.options.success instanceof Function) this.options.success(value)
                    return
                }

                if (this.options.fail instanceof Function) this.options.fail(value)
            })

            resolve(res)
        })

    }

    writeValue(characteristic) {
        console.log('writeValue', characteristic, this.options)
        return new Promise(async (resolve, reject) => {

            let mac = this.options.bluetoothMac.split(':')
            let uuids = `01${mac[mac.length-3]}${mac[mac.length-2]}${mac[mac.length-1]}`
            if (this.options.type === CONST.BluetoothTypeOffCharge)            uuids += `010000000000000000`
            else if (this.options.type === CONST.BluetoothTypeStartCharge)     uuids += `01${BluetoothPowerMinute(this.options.powerMinute)}000000000000`
            else if (this.options.type === CONST.BluetoothTypeStartChannelOne) uuids += `000100000000000000`
            else if (this.options.type === CONST.BluetoothTypeStartChannelTwo) uuids += `000001000000000000`
            else return reject('type is err')

            API.getDevPasswordVerify({ message: uuids, type: 1 }).then(async res => {
                console.log('getDevPasswordVerify', res)
                if(!res.result) return reject('password err')
                uuids += res.result

                await this.timeSleep(800)
                let wRes = await this.writeBLECharacteristicValue(characteristic, uuids)
                this.options.successTime = setTimeout(ev => {
                    if (this.options.success instanceof Function) this.options.success(wRes)
                }, 2600)
                resolve(wRes)
            }).catch(err => {
                reject(err)
            })
        })
    }
}

// 蓝牙密码连接[第四版]
class BluetoothPassword4 extends Bluetooth {
    async initConnection() {
        try {
            console.log('initConnection-start')
            await this.openBluetoothAdapter()

            let connectionDevices = this.getConnectionDevices()
            if (await this.getConnectedDevices(connectionDevices)) return

            let device = this.options.device
            if(!device || !device.deviceId) device = await this.startBluetoothDevicesDiscovery()

            let services = await this.createBLEConnection(device.deviceId)
            let characteristicAllList = await this.getBLEDeviceCharacteristicsAll(device.deviceId, services)
            console.log('characteristicAllList', characteristicAllList)

            let saveData = {}
            for (let characteristic of characteristicAllList) {
                if (characteristic.characteristicId.toUpperCase().indexOf('FFE1') > -1) {
                    saveData.writeServer = characteristic
                }
                if (characteristic.characteristicId.toUpperCase().indexOf('FFE1') > -1) {
                    saveData.notifyServer = characteristic
                }
            }

            if(!saveData.writeServer || !saveData.notifyServer ) {
                if (this.options.fail instanceof Function) this.options.fail('设备暂不支持')
                return
            }

            await this.notifyValueChange(saveData)
            await this.writeValue(saveData.writeServer)
            this.saveConnectionDevices(this.options.deviceSn, saveData)
        } catch (err) {
            console.log('initConnection', err)
            if (this.options.fail instanceof Function) this.options.fail(err)
        }
    }

    // 查询连接状态
    getConnectedDevices(connectionDevices) {
        return new Promise(async (resolve, reject) => {
            console.log('getConnectedDevices', connectionDevices)
            if (!connectionDevices.writeServer) return resolve(false)
            let devices = await this.getConnectedBluetoothDevices(connectionDevices.writeServer)
            for (let device of devices) if (device.deviceId === connectionDevices.writeServer.deviceId) {
                await this.notifyValueChange(connectionDevices)
                await this.writeValue(connectionDevices.writeServer)
                return resolve(true)
            }
            this.deleteConnectionDevices(this.options.deviceSn)
            resolve(false)
        })
    }

    notifyValueChange(connectionDevices) {
        console.log('notifyValueChange', connectionDevices)
        const { notifyServer, writeServer } = connectionDevices
        return new Promise(async (resolve, reject) => {
            let res = await this.notifyBLECharacteristicValueChange(notifyServer, nRes => {
                let value = nRes.value.toUpperCase()
                clearTimeout(this.options.successTime)
                console.log('notifyBLECharacteristicValueChange', value, nRes)
                if (value.slice(4,6) === "") {
                    return
                }

                if (value.slice(4,6) === "00") {
                    if (this.options.success instanceof Function) this.options.success(value)
                    return
                }

                if (this.options.fail instanceof Function) this.options.fail(value)
            })

            resolve(res)
        })

    }

    writeValue(characteristic) {
        console.log('writeValue', characteristic, this.options)
        return new Promise(async (resolve, reject) => {

            let mac = this.options.bluetoothMac.split(':')
            let uuids = `01${mac[mac.length-3]}${mac[mac.length-2]}${mac[mac.length-1]}`
            if (this.options.type === CONST.BluetoothTypeOffCharge)            uuids += `0000`
            else if (this.options.type === CONST.BluetoothTypeStartCharge)     uuids += `${BluetoothPowerMinute(this.options.powerMinute)}`
            else return reject('type is err')

            API.getDevPasswordVerify({ message: uuids, type: 2 }).then(async res => {
                console.log('getDevPasswordVerify', res)
                if(!res.result) return reject('password err')
                uuids += res.result

                await this.timeSleep(800)
                let wRes = await this.writeBLECharacteristicValue(characteristic, uuids)
                this.options.successTime = setTimeout(ev => {
                    if (this.options.success instanceof Function) this.options.success(wRes)
                }, 2600)
                resolve(wRes)
            }).catch(err => {
                reject(err)
            })
        })
    }
}

function openBluetoothGroupPasswordXm(options) {
    console.log('openBluetoothGroupPasswordXm-start', options)
    let ble = new BluetoothGroupPasswordXm(options)
    ble.initConnection()
}

function openBluetoothGroupPassword(options) {
    console.log('openBluetoothGroupPassword-start', options)
    let ble = new BluetoothGroupPassword(options)
    ble.initConnection()
}

function openBluetoothChangePassword(options) {
    console.log('openBluetoothChangePassword-start', options)
    let ble = new BluetoothChangePassword(options)
    ble.initConnection()
}

function openBluetoothPassword(options) {
    console.log('openBluetoothPassword-start', options)
    let ble = new BluetoothPassword(options)
    ble.initConnection()
}

function openBluetoothPassword4(options) {
    console.log('openBluetoothPassword-start', options)
    let ble = new BluetoothPassword4(options)
    ble.initConnection()
}

// 搜索蓝牙
async function searchBluetooth(options) {
    console.log('searchBluetooth', options)
    let ble = new Bluetooth(options)
    try {

        await ble.openBluetoothAdapter()
        let res = await ble.startBluetoothDevicesDiscovery()
        if (options.success instanceof Function) options.success(res)
    }catch (err) {
        if (options.fail instanceof Function) options.fail(err)
    }


    //     .then(res => {
    //     if (options.success instanceof Function) options.success(res)
    // }).catch(err => {
    //     if (options.fail instanceof Function) options.fail(err)
    // })
}

module.exports = {
    openBluetoothGroupPasswordXm,
    openBluetoothGroupPassword,
    openBluetoothChangePassword,
    openBluetoothPassword4,
    openBluetoothPassword,
    searchBluetooth
}
